package la.iok.hzsvn.lewin.movie.service;

import la.iok.hzsvn.lewin.movie.core.exception.ErrorCode;
import la.iok.hzsvn.lewin.movie.core.model.PlayRoleInstVo;
import la.iok.hzsvn.lewin.movie.core.model.PlayRoleVo;
import la.iok.hzsvn.lewin.movie.entity.PlayRole;
import la.iok.hzsvn.lewin.movie.entity.PlayRoleInstance;
import la.iok.hzsvn.lewin.movie.mapper.PlayRoleInstanceMapper;
import la.iok.hzsvn.lewin.mybatis.service.BaseServiceImpl;
import la.iok.hzsvn.share.annotations.NotNull;
import la.iok.hzsvn.share.annotations.NotNullElement;
import la.iok.hzsvn.share.annotations.NullElement;
import la.iok.hzsvn.share.annotations.Nullable;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class PlayRoleInstanceServiceImpl extends BaseServiceImpl<PlayRoleInstance, PlayRoleInstanceMapper,Long> implements PlayRoleInstanceService {
    private final PlayRoleFileService playRoleFileService;
    public PlayRoleInstanceServiceImpl(PlayRoleInstanceMapper mapper, PlayRoleFileService playRoleFileService) {
        super(mapper);
        this.playRoleFileService = playRoleFileService;
    }

    @NotNull
    @Override
    public Long save(@NotNull PlayRole role, @NotNull Long movieInstanceId) {
        PlayRoleInstance instance = new PlayRoleInstance();
        BeanUtils.copyProperties(role,instance);
        instance.setId(null);
        instance.setMovieInstanceId(movieInstanceId);
        instance.setPlayRoleId(role.getId());
        insertSelective(instance);
        playRoleFileService.increment(instance.getFileId());
        return instance.getId();
    }

    @Override
    public String digest(@Nullable Long movieInstanceId, @Nullable Long playRoleId) {
        if(movieInstanceId == null || playRoleId == null){
            return null;
        }
        PlayRoleInstance instance = mapper.select(movieInstanceId,playRoleId);
        ErrorCode.PLAY_ROLE_NOT_EXIST.assertNotNull(instance,playRoleId);
        return playRoleFileService.digest(instance.getFileId());
    }

    @Override
    public String storePath(@Nullable Long movieInstanceId, @Nullable Long playRoleId) {
        if(movieInstanceId == null || playRoleId == null){
            return null;
        }
        PlayRoleInstance instance = mapper.select(movieInstanceId,playRoleId);
        ErrorCode.PLAY_ROLE_NOT_EXIST.assertNotNull(instance,playRoleId);
        return playRoleFileService.storePath(instance.getFileId());
    }

    @Override
    public PlayRoleInstVo select(Long movieInstanceId, Long playRoleId) {
        if(movieInstanceId == null || playRoleId == null){
            return null;
        }
        PlayRoleInstance instance = mapper.select(movieInstanceId,playRoleId);
        ErrorCode.PLAY_ROLE_NOT_EXIST.assertNotNull(instance,playRoleId);
        PlayRoleInstVo vo = new PlayRoleInstVo();
        BeanUtils.copyProperties(instance,vo);
        return vo;
    }

    @NotNull
    @NotNullElement
    @Override
    public List<PlayRoleVo> movieRoles(@Nullable Long movieInstanceId) {
        if(movieInstanceId == null){
            return Collections.emptyList();
        }
        List<PlayRoleInstance> roles = listByProperty("movieInstanceId",movieInstanceId);
        return roles.stream().map(this::po2vo).collect(Collectors.toList());
    }

    @Override
    public void downloadFile(@NotNull HttpServletResponse response, @Nullable Long movieInstanceId, @Nullable Long playRoleId) {
        if(movieInstanceId == null || playRoleId == null){
            return;
        }
        PlayRoleInstance instance = mapper.select(movieInstanceId,playRoleId);
        ErrorCode.PLAY_ROLE_NOT_EXIST.assertNotNull(instance,playRoleId);
        playRoleFileService.downloadFile(response,instance.getFileId(),instance.getName());
    }

    @Override
    public void markFileDeleted(@Nullable @NullElement Collection<Long> ids) {
        batchUpdate("fileDeleted",1, ids);
    }

    public PlayRoleVo po2vo(PlayRoleInstance po){
        PlayRoleVo vo = new PlayRoleVo();
        BeanUtils.copyProperties(po,vo);
        vo.setId(po.getPlayRoleId());
        return vo;
    }
}
